import i18n from "@/assets/lang/index";

export function ruleString(
  required = true,
  min = 0,
  max = 255,
  label = "",
  trigger = "blur"
) {
  let rule = [
    {
      type: "string",
      required: required,
      message: i18n.global.t("rule.string.requiredError", [label]),
      trigger: trigger,
    },
    {
      validator(rule, value, callback) {
        if (value != null) {
          if (min != null && max == null) {
            value.length >= min ||
              callback(
                new Error(
                  i18n.global.t("rule.string.lessThanMin", [label, min])
                )
              );
          } else if (min == null && max != null) {
            value.length <= max ||
              callback(
                new Error(
                  i18n.global.t("rule.string.GreaterThanMax", [label, max])
                )
              );
          } else if (min != null && max != null) {
            (value.length <= max && value.length >= min) ||
              callback(
                new Error(
                  i18n.global.t("rule.string.notBetween", [label, min, max])
                )
              );
          }
        }
        callback();
      },
      trigger: trigger,
    },
  ];
  return rule;
}

export function ruleDate(required = true, label = "", trigger = "change") {
  let rule = [
    {
      required: required,
      message: i18n.global.t("rule.date.requiredError", [label]),
      trigger: trigger,
    },
    {
      type: "date",
      message: i18n.global.t("rule.date.typeError", [label]),
      trigger: trigger,
    },
  ];
  return rule;
}
/*
数字：^[0-9]*$
n位的数字：^\d{n}$
至少n位的数字：^\d{n,}$
m-n位的数字：^\d{m,n}$
零和非零开头的数字：^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字：^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1-2位小数的正数或负数：^(\-)?\d+(\.\d{1,2})?$
正数、负数、和小数：^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数：^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数：^[0-9]+(.[0-9]{1,3})?$
非零的正整数：^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数：^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非负整数：^\d+$ 或 ^[1-9]\d*|0$
非正整数：^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数：^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数：^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数：^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数：^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数：^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
匹配中文字符的正则表达式： [\u4e00-\u9fa5]

匹配双字节字符(包括汉字在内)：[^\x00-\xff]
评注：可以用来计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）

匹配空白行的正则表达式：\n\s*\r
评注：可以用来删除空白行

匹配HTML标记的正则表达式：<(\s*?)[^>]*>.*?|<.*?>
评注：网上流传的版本太糟糕，上面这个也仅仅能匹配部分，对于复杂的嵌套标记依旧无能为力

匹配首尾空白字符的正则表达式：^\s*|\s*$
评注：可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)，非常有用的表达式

匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注：表单验证时很实用

匹配网址URL的正则表达式：[a-zA-z]+://[^\s]*
评注：网上流传的版本功能很有限，上面这个基本可以满足需求

匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注：表单验证时很实用

匹配国内电话号码：\d{3}-\d{8}|\d{4}-\d{7}
评注：匹配形式如 0511-4405222 或 021-87888822

匹配腾讯QQ号：[1-9][0-9]{4,}
评注：腾讯QQ号从10000开始

匹配中国邮政编码：[1-9]\d{5}(?!\d)
评注：中国邮政编码为6位数字

匹配身份证：\d{15}|\d{18}
评注：中国的身份证为15位或18位

匹配ip地址：\d+\.\d+\.\d+\.\d+
评注：提取ip地址时有用

匹配特定数字：
^[1-9]\d*$ //匹配正整数
^-[1-9]\d*$  //匹配负整数
^-?[1-9]\d*$ //匹配整数
^[1-9]\d*|0$ //匹配非负整数（正整数 + 0）
^-[1-9]\d*|0$ //匹配非正整数（负整数 + 0）
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非负浮点数（正浮点数 + 0）
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$//匹配非正浮点数（负浮点数 + 0）
评注：处理大量数据时有用，具体应用时注意修正

匹配特定字符串：
^[A-Za-z]+$//匹配由26个英文字母组成的字符串
^[A-Z]+$//匹配由26个英文字母的大写组成的字符串
^[a-z]+$//匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$//匹配由数字和26个英文字母组成的字符串

^\w+$//匹配由数字、26个英文字母或者下划线组成的字符串
 */
export function ruleNumber(
  required = true,
  min = 0,
  max,
  label,
  trigger = "blur"
) {
  let rule = [
    {
      required: required,
      message: i18n.global.t("rule.number.requiredError", [label]),
      trigger: trigger,
    },
    {
      validator(rule, value, callback) {
        if (value) {
          if (!/^(\\-|\+)?\d+(\.\d+)?$/.test(value)) {
            callback(
              new Error(i18n.global.t("rule.number.notNumber", [label]))
            );
          } else {
            let n = Number.parseFloat(value);
            if (min != null && max == null) {
              n >= min ||
                callback(
                  new Error(
                    i18n.global.t("rule.number.lessThanMin", [label, min])
                  )
                );
            } else if (min == null && max != null) {
              n <= max ||
                callback(
                  new Error(
                    i18n.global.t("rule.number.GreaterThanMax", [label, max])
                  )
                );
            } else if (min != null && max != null) {
              (n <= max && n >= min) ||
                callback(
                  new Error(
                    i18n.global.t("rule.number.notBetween", [label, min, max])
                  )
                );
            }
          }
        }
        callback();
      },
      trigger: "blur",
    },
  ];
  return rule;
}

// 匹配长度为N的数字
export function ruleLengthNumber(
  required = true,
  min = 0,
  max = 256,
  label = "",
  trigger = "blur"
) {
  let rule = [
    {
      type: "string",
      required: required,
      message: i18n.global.t("rule.string.requiredError", [label]),
      trigger: trigger,
    },
    {
      validator(rule, value, callback) {
        if (value) {
          if (!/^(\\-|\+)?\d+(\.\d+)?$/.test(value)) {
            callback(
              new Error(i18n.global.t("rule.number.notNumber", [label]))
            );
          } else if (min != null && max == null) {
            value.length >= min ||
              callback(
                new Error(
                  i18n.global.t("rule.string.lessThanMin", [label, min])
                )
              );
          } else if (min == null && max != null) {
            value.length <= max ||
              callback(
                new Error(
                  i18n.global.t("rule.string.GreaterThanMax", [label, max])
                )
              );
          } else if (min != null && max != null) {
            (value.length <= max && value.length >= min) ||
              callback(
                new Error(
                  i18n.global.t("rule.string.notBetween", [label, min, max])
                )
              );
          }
        }
        callback();
      },
      trigger: trigger,
    },
  ];
  return rule;
}

export function ruleRegex(required = true, regex, label, trigger = "blur") {
  let rule = [
    {
      required: required,
      message: i18n.global.t("rule.regex.requiredError", [label]),
      trigger: trigger,
    },
    {
      validator(rule, value, callback) {
        if (value != null) {
          if (!regex.test(value)) {
            callback(new Error(i18n.global.t("rule.regex.notMatch", [label])));
          }
        }
        callback();
      },
      trigger: "blur",
    },
  ];
  return rule;
}
/*string: Must be of type string. This is the default type.
number: Must be of type number.
boolean: Must be of type boolean.
method: Must be of type function.
regexp: Must be an instance of RegExp or a string that does not generate an exception when creating a new RegExp.
integer: Must be of type number and an integer.
float: Must be of type number and a floating point number.
array: Must be an array as determined by Array.isArray.
object: Must be of type object and not Array.isArray.
enum: Value must exist in the enum.
date: Value must be valid as determined by Date
url: Must be of type url.
hex: Must be of type hex.
email: Must be of type email.
any: Can be any type.*/
export function ruleOther(
  required = true,
  type = "string",
  min = 0,
  max = 256,
  label = "",
  trigger = "change"
) {
  let rule = [
    {
      required: required,
      message: i18n.global.t("rule.other.requiredError", [label]),
      trigger: trigger,
    },
    {
      validator(rule, value, callback) {
        if (value != null) {
          if (min != null && max == null) {
            value.length >= min ||
              callback(
                new Error(i18n.global.t("rule.other.lessThanMin", [label, min]))
              );
          } else if (min == null && max != null) {
            value.length <= max ||
              callback(
                new Error(
                  i18n.global.t("rule.other.GreaterThanMax", [label, max])
                )
              );
          } else if (min != null && max != null) {
            (value.length <= max && value.length >= min) ||
              callback(
                new Error(
                  i18n.global.t("rule.other.notBetween", [label, min, max])
                )
              );
          }
        }
        callback();
      },
    },
    {
      type: type,
      message: i18n.global.t("rule.other.typeError", [label]),
    },
  ];
  return rule;
}
